/**
 * @addtogroup jtc_msg_808
 * jtc_msg_808_mgr
 * @{
 */
 /**
 * @file         jtc_msg_808_mgr.h
 * @brief        交通部消息808管理器
 * @note    
 * @author       Akee
 * @date         2019-10-30
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2019-10-30  <td>1.0                   <td>Akee            <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _JTC_MSG_808_MGR_H_
#define _JTC_MSG_808_MGR_H_

#include "ofc/ofc_list.h"
#include "jtmsg808/jtc_msg_808.h"
#include "jtmsg808/jtc_msg_808_codec.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
 * 创建广播事件
 * @param sender: 发起者，这里指TJtMsg808Mgr
 * @param receiver: 接收者
 * @param msg_head: 交通部消息头
 * @return 
 */
typedef void (*TJtMsg808MgrDoCreateBroadcast)(void *sender, void *receiver, TJtMsg808Head *msg_head);
/**
 * 创建广播对象
 */
typedef struct TJtMsg808MgrOnCreateBroadcastTag TJtMsg808MgrOnCreateBroadcast;
struct TJtMsg808MgrOnCreateBroadcastTag
{
    void *object;                           ///< 对象
    TJtMsg808MgrDoCreateBroadcast Method;   ///< 方法
};

/**
 * 交通部消息808管理器
 */
typedef struct TJtMsg808MgrTag TJtMsg808Mgr;
struct TJtMsg808MgrTag
{
    TOfObject parent_;                ///< 基类

PROTECTED
    TOfVirtualMethod Destroy_;        ///< 析构事件

PUBLIC
    TJtMsg808MgrOnCreateBroadcast OnCreateBroadcast;    ///< 创建广播事件
    TJtMsg808OnMsgProcEvent OnMsgProcBroadcast;         ///< 消息广播事件

PRIVATE
    Byte sim_no_[11];                 ///< sim卡号
    Byte ver_;                        ///< 版本,参考TJtMsg808VerEnum    
    Word msg_seq_id_;                 ///< 消息流水号
    Int32 tcp_timeout_;               ///< tcp超时时间,单位: 秒
    Int32 tcp_retry_count_;           ///< tcp重试次数
    TOfList create_msg_list_;         ///< 消息创建list
    TOfList msg_8001_list_;           ///< 0x8001的消息注册数组
    TOfList msg_8900_list_;           ///< 0x8900的消息注册数组
    //TOfList msg_8003_list_;           ///< 0x8003的消息注册数组
};

/**
 * 构造函数
 * @param self: 对象指针
 * @param ver: 版本,参考TJtMsg808VerEnum
 * @return 
 */
void TJtMsg808MgrCreate(TJtMsg808Mgr *self, Byte ver);

Bool TJtMsg808MgrInit(TJtMsg808Mgr *self);

void TJtMsg808MgrDone(TJtMsg808Mgr *self);

/**
 * 注册消息构造事件
 * @param self: 对象指针
 * @param msg_id: 消息id
 * @param fixed_size: 消息大小
 * @param ver: 消息版本号
 * @param do_create: 构造函数
 * @return True: 成功; False: 失败
 * @note 内部会注册0x8001和0x8900,外部不建议注册
 */
Bool TJtMsg808MgrRegisterOnCreate(TJtMsg808Mgr *self, Word msg_id, Word fixed_size, Byte ver, 
    TJtMsg808DoCreateEvent do_create);

/**
 * 注册消息处理事件函数
 * @param self: 对象指针
 * @param msg_id: 消息id
 * @param ver: 消息版本号
 * @param msg_proc_object: 消息处理事件的接收者
 * @param msg_proc_event: 消息处理事件
 * @return True: 成功; False: 失败
 * @note 内部会注册0x8001和0x8900,若需要此2项消息，则用专项接口TJtMsg808MgrRegister8001MsgProc和TJtMsg808MgrRegister8900MsgProc
 */
Bool TJtMsg808MgrRegisterOnMsgProc(TJtMsg808Mgr *self, Word msg_id, Byte ver, void *msg_proc_object, 
    TJtMsg808DoMsgProcEvent msg_proc_event);

/**
 * 通过版本号调用分发消息函数
 * @param self: 对象指针
 * @param msg_808: 消息
 * @param ver: 消息版本号
 * @return True: 成功; False: 失败
 */
Bool TJtMsgMsgMgrCallMsgProcWithVer(TJtMsg808Mgr *self, TJtMsg808 *msg_808, Byte ver, struct IJtMsg808SessionTag *session);

/**
 * 通过索引号调用分发消息函数,已经索引的位置时才允许调用
 * @param self: 对象指针
 * @param msg_808: 消息
 * @param index: 调用的索引号
 * @return True: 成功; False: 失败
 */
Bool TJtMsgMsgMgrCallMsgProcWithIndex(TJtMsg808Mgr *self, TJtMsg808 *msg_808, int index, struct IJtMsg808SessionTag *session);

/**
 * 清除注册事件
 * @param self: 对象指针
 * @return
 */
void TJtMsg808MgrClearRegisters(TJtMsg808Mgr *self);

/**
 * 创建消息
 * @param self: 对象指针
 * @param msg_head: 消息头
 * @param item_inde: 项
 * @return NULL: 失败; 其他: 消息指针,消息需要通过TJtMsg808MgrFreeMsg释放
 */
TJtMsg808 *TJtMsg808MgrCreateMsg(TJtMsg808Mgr *self, TJtMsg808Head *msg_head, int *item_index);

/**
 * 获取sim卡号
 * @param self: 对象指针
 * @return sim卡号
 */
const char *TJtMsg808MgrSimNo(TJtMsg808Mgr *self);

/**
 * 获取sim卡尺寸大小
 * @param self: 对象指针
 * @return 卡尺寸大小，不同版本的sim卡尺寸不一样
 */
Int32 TJtmsg808MgrGetSimNoSize(TJtMsg808Mgr *self);

/**
 * 获取sim卡号
 * @param self: 对象指针
 * @param buf: 存放sim卡大小的缓存
 * @param buf_size: 存放sim卡大小的缓存大小
 * @return 实际获取的卡尺寸大小，不同版本的sim卡尺寸不一样
 */
int TJtMsg808MgrGetSimNo(TJtMsg808Mgr *self, Byte *buf, Int32 buf_size);

/**
 * 设置sim卡号
 * @param self: 对象指针
 * @param sim_phone_no: 设置sim卡大小的缓存,Ascii码
 * @param sim_phone_no_size: 设置sim卡大小的缓存大小
 * @return 
 */
void TJtMsg808MgrSetSimNo(TJtMsg808Mgr *self, Int8 *sim_phone_no);

/**
 * 设置sim卡号Bcd
 * @param self: 对象指针
 * @param sim_phone_no_bcd: 设置sim卡大小的缓存,Bcd码
 * @param sim_phone_no_bcd_len: 设置sim卡大小的缓存大小
 * @return 
 */
void TJtMsg808MgrSetSimNoBcd(TJtMsg808Mgr *self, Int8 *sim_phone_no_bcd, Int32 sim_phone_no_bcd_len);

/**
 * 获取版本号
 * @param self: 对象指针
 * @return 版本号,参考TJtMsg808VerEnum
 */
Byte TJtMsg808MgrVer(TJtMsg808Mgr *self);

/**
 * 获取Tcp超时时间
 * @param self: 对象指针
 * @return 超时时间,单位: 秒
 */
Int32 TJtMsg808MgrTcpTimeout(TJtMsg808Mgr *self);

/**
 * 设置Tcp超时时间,内部限制最小10秒
 * @param self: 对象指针
 * @param value: 超时时间,单位: 秒
 * @return 
 */
void TJtMsg808MgrSetTcpTimeout(TJtMsg808Mgr *self, Int32 value);

/**
 * 获取Tcp重试次数
 * @param self: 对象指针
 * @return 重试次数
 */
Int32 TJtMsg808MgrTcpRetryCount(TJtMsg808Mgr *self);

/**
 * 设置Tcp重试次数
 * @param self: 对象指针
 * @param value: 重试次数
 * @return 
 */
void TJtMsg808MgrSetTcpRetryCount(TJtMsg808Mgr *self, Int32 value);

/**
 * 获取下一个流水号
 * @param self: 对象指针
 * @return 下一个流水号
 */
Word TJtMsg808MgrGetNextSeqId(TJtMsg808Mgr *self);

/**
 * 获取下一块连续的流水号
 * @param self: 对象指针
 * @param count: 连续的流水号个数
 * @return 下一个流水号
 */
Word TJtMsg808MgrGetNextSeqIdEx(TJtMsg808Mgr *self, Word count);

/**
 * 设置流水号
 * @param self: 对象指针
 * @param value: 流水号
 * @return
 */
void TJtMsg808MgrSetSeqId(TJtMsg808Mgr *self, Word value);

/**
 * 获取消息和版本号的组合字段
 * @param self: 对象指针
 * @param msg_id: 消息id
 * @param ver: 版本号
 * @return (msg_id | (ver < 16))
 */
DWord TJtMsg808MgrGetMsgIdVer(TJtMsg808Mgr *self, Word msg_id, Byte ver);

/**
 * 应用0x8001消息处理事件函数
 * @param self: 对象指针
 * @param resp_msg_id: 应答消息id
 * @param ver: 消息版本号,参考TJtMsg808VerEnum
 * @param msg_proc_object: 消息处理事件的接收者
 * @param msg_proc_event: 消息处理事件
 * @return True: 成功; False: 失败
 * @note 重复注册的应答消息id时，会覆盖先注册的事件
 */
Bool TJtMsg808MgrRegister8001MsgProc(TJtMsg808Mgr *self, Word resp_msg_id, Byte ver,
    const void *msg_proc_object, TJtMsg808DoMsgProcEvent msg_proc_event);

/**
 * 应用0x8900消息处理事件函数
 * @param self: 对象指针
 * @param type: 类型,参考TJtMsg808ByPassTypeEnum
 * @param ver: 消息版本号,参考TJtMsg808VerEnum
 * @param msg_proc_object: 消息处理事件的接收者
 * @param msg_proc_event: 消息处理事件
 * @return True: 成功; False: 失败
 * @note 允许重复注册类型
 */
Bool TJtMsg808MgrRegister8900MsgProc(TJtMsg808Mgr *self, Byte type, Byte ver,
    const void *msg_proc_object, TJtMsg808DoMsgProcEvent msg_proc_event);
#ifdef __cplusplus
} // extern "C" {
#endif
#endif
/**
 * @} 
 */

